---
title: Cross Chain Contract Calls
description: Example call on Babylon to Ethereum contract.
---

This guide walks you through writing our example ["Call"](/integrations/typescript/examples/cosmos/call/). The goal of this guide is to show you how to conduct a cross chain contract call using [ucs03-zkgm](/ucs/03/). In this case we will be calling a contract on Ethereum from Babylon.

Relevant imports will be included with each step. Outside of libraries provided by Union, this guide uses [Effect](https://effect.website/).

## Program

This first section is a walk through of creating the program section of the send funds example.

### 1. Program Declaration

Begin by using Effect to create a program function.

The signer used for this transaction is also declared here.

```ts
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"
import { Effect, Logger } from "effect"

const signer = await DirectSecp256k1HdWallet.fromMnemonic(
  process.env.MEMO ?? "memo memo memo",
  { prefix: "bbn" },
)

const program = Effect.gen(function*() {})
```

### 2. Source and Destination

Using the `ChainRegistry` from the Union TS SDK, you can declare the source and destination chains used in this example. In this case, the source is Babylon (`babylon.bbn-1`) and the destination is Ethereum (`ethereum.1`).

```ts
import { ChainRegistry } from "@unionlabs/sdk/ChainRegistry"
import { UniversalChainId } from "@unionlabs/sdk/schema/chain"
import { Effect, Logger } from "effect"

const program = Effect.gen(function*() {
  const source = yield* ChainRegistry.byUniversalId(
    UniversalChainId.make("babylon.bbn-1"),
  )

  const destination = yield* ChainRegistry.byUniversalId(
    UniversalChainId.make("ethereum.1"),
  )
})
```

:::note
The IDs provided here are Universal Chain IDs as defined by [ucs04](/ucs/04).
:::

### 3. Call

To create a `Call`, we supply the `sender`, `contractAddress`, and `contractCalldata`.

More information about `Call` and its fields can be found in the [Call](/ucs/03/#0x01---call) docs.

```ts
import { Call, Ucs05, ZkgmClientRequest, ZkgmClientResponse } from "@unionlabs/sdk"
import { Effect, Logger } from "effect"

const program = Effect.gen(function*() {

  // ... snip ...

  const call = Call.make({
    sender: Ucs05.CosmosDisplay.make({
      address: "bbn122ny3mep2l7nhtafpwav2y9e5jrslhekrn8frh",
    }),
    eureka: false,
    contractAddress: Ucs05.EvmDisplay.make({
      address: "0x921e5b5091f431f84f14423ec487783a853bc4b0",
    }),
    contractCalldata: "0xDEADBEEF",
  })
})
```

### 4. zkgm Request

Finally, with the `Call` ready - you can construct a `ZkgmClientRequest`.

```ts
import { Call, Ucs05, ZkgmClientRequest, ZkgmClientResponse } from "@unionlabs/sdk"
import { Effect, Logger } from "effect"

const program = Effect.gen(function*() {

  // ... snip ...

  const request = ZkgmClientRequest.make({
    source,
    destination,
    channelId: ChannelId.make(3),
    ucs03Address: "bbn1336jj8ertl8h7rdvnz4dh5rqahd09cy0x43guhsxx6xyrztx292q77945h",
    instruction: call,
  })
})
```

:::note
ucs03 addresses can be found on the [Deployments page](/protocol/deployments/)
:::

### 5. zkgm Execution and Response

Now that you’ve created a full zkgm request, you can execute it and wait on the response to close out the program.

```ts
import { Call, Ucs05, ZkgmClientRequest, ZkgmClientResponse } from "@unionlabs/sdk"
import { GasPrice } from "@cosmjs/stargate"
import { Cosmos, CosmosZkgmClient } from "@unionlabs/sdk-cosmos"
import { Effect, Logger } from "effect"
const program = Effect.gen(function*() {

  // ... snip ...

  const client = yield* CosmosZkgmClient.make.pipe(
    Effect.provide(Cosmos.SigningClient.Live(
      "bbn122ny3mep2l7nhtafpwav2y9e5jrslhekrn8frh",
      "https://rpc.bbn-1.babylon.chain.kitchen",
      signer,
      { gasPrice: GasPrice.fromString("0.0007ubbn") },
    )),
    Effect.provide(Cosmos.Client.Live("https://rpc.bbn-1.babylon.chain.kitchen")),
  )

  const response: ZkgmClientResponse.ZkgmClientResponse = yield* client.execute(request)

  yield* Effect.log("TX Hash:", response.txHash)
})
```

## Execution

With the program ready, we can now use Effect to execute our transfer and listen for a response.

```ts
const program = Effect.gen(function*() {
  // ... program ...
}).pipe(
  Effect.provide(ChainRegistry.Default),
  Effect.provide(Logger.replace(Logger.defaultLogger, Logger.prettyLoggerDefault)),
)

Effect.runPromise(program)
  .then(console.log)
  .catch(console.error)
```
